<?php
/**
 * 牛年求牛：有一母牛，到4岁可生育，每年一头，所生均是一样的母牛，到15岁绝育，不再能生，20岁死亡，问n年后有多少头牛？
 */

/**
* 数组计算，最高只能计算到45年，因为内存不够。该方法太耗费资源，遂改变
*/

function calculatorNumberOne(int $year=1)
{
    //默认一头牛，一个元素就是一头牛，其值为年龄
    $cattles = [
        1=>1
    ];

    //每循环一次，一头牛增加一岁，满20便死亡
    //每循环一次，满4岁的牛可生育，15岁绝育。
    for ($i=1; $i <= $year; $i+=1 ) {
        foreach ($cattles as $num => $age) {
            //满20岁，该牛死亡。
            if($age >= 20){
                unset($cattles[$num]);
                continue;
            }
            //满足该条件即生出一头牛
            if($age >= 4 && $age < 15){
                $cattles[] = 1;
            }

            //牛的年龄加1
            $cattles[$num] += 1;
        }
    }
    return count($cattles);
}
$year = 45;
echo '按这样的计算方式，',$year,'年后，牛的数量为：',calculatorNumberOne(45);
echo '<hr/><br/>';

/**
* 时间刻度，从左到右逐年递增。
* 年龄刻度，从左到右递增，最左边的起始值为$cattles[1]，即第一年。
* 该计算最大支持2236，因为超过最大值，返回INF。
* 完成时间：20180110
*/
function calculatorNumber(int $year)
{
    //key为年龄，值为牛数量
    $cattles = [
        1 => 1
    ];
    
    //按年循环，每次增加1
    //每循环一次，一头牛增加一岁，满20便死亡
    //每循环一次，满4岁的牛可生育，15岁绝育。
    for ($i=1; $i <= $year; $i+=1 ) {
        //确定今年可以生育多少头牛，每年符合生育条件的牛都会生育一头
        $lifes = array_slice($cattles, 3 , 11 ,true);
        array_unshift($cattles, array_sum($lifes));
        //20岁牛死亡
        if (isset($cattles['20'])) {
            unset($cattles['20']);
        }
    }
    //最终牛的数量
    $number = array_sum($cattles);
    return $number;
}

//2236为可表现的最大值
$year = 2236;
echo '按这样的计算方式，',$year,'年后，牛的数量为：',calculatorNumber($year);